/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pope.jloading.downloader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import pope.jloading.Elog;

/**
 *
 * @author pope945@gmail.com
 */
public class Config {
    private String configPath;
    private Document doc;

    public Config(Document doc, String configPath) {
        this.doc = doc;
        this.configPath = configPath;
    }
    
    /**
     * 获取当前状�?文件的保存路�?     * @return configPath
     */
    public String getConfigPath() {
        return configPath;
    }
    
    /** 任务标识,这个标识用于区别每个不同的任务，应该是绝对的唯一*/
    public String getId() {
        Element file = doc.getDocumentElement();
        String id = file.getAttribute("id");
        return id;
    }
    
    /**
     * 获取短文件名,不包括后�?��，也不包括文件路径等信息
     * @return name
     */
    public String getName() {
        Element file = doc.getDocumentElement();
        String filename = file.getAttribute("name");
        return filename;
    }
    
    /**
     * 获取sid 
     * @return name
     */
    public String getSid() {
        Element file = doc.getDocumentElement();
        String sid = file.getAttribute("sid");
        return sid ;
    }
    /**
     * 获取是否要进行切换动作，区别是下载并切换动作和 “仅下载”
     * @return
     */
    public String getAction(){
    	Element file = doc.getDocumentElement();
        String is2change = file.getAttribute("action");
        return is2change ;
    }
    
    
    /**
     * 获取�?��文件名，包括完整的绝对路�?即完整的文件保存路径级后�?��,
     * 这是�?��下载完任务之后的路径及文件名
     * @return save
     */
    public String getSave() {
        Element file = doc.getDocumentElement();
        String filename = file.getAttribute("save");
        return filename;
    }
    
    /**
     * 获取文件的长�?字节)
     * @return length
     */
    public long getLength() {
        Element file = doc.getDocumentElement();
        long length = Long.valueOf(file.getAttribute("length"));
        return length;
    }
    
    /**
     * 获取原始的线程数,如果没有设置，则返回1
     * @return threads
     */
    public int getThreads() {
        Element file = doc.getDocumentElement();
        int s = Integer.valueOf(file.getAttribute("threads"));
        return s >= 0 ? s : 1;
    }
    
    /**
     * 获取状�?保存文件中的资源地址(即下载源),在有可能的情况下，可以让任务支持
     * 多个下载源，即从多个URL地址中同时下载一个文件�?
     * @return urls
     */
    public List<String> getURLs() {
        List<String> urls = new ArrayList<String>();
        Element file = doc.getDocumentElement();
        Element eURLs = (Element) file.getElementsByTagName("urls").item(0);
        NodeList nURLs = eURLs.getElementsByTagName("url");
        int len = nURLs.getLength();
        for (int i = 0; i < len; i++) {
            Element eURL = (Element) nURLs.item(i);
            String src = eURL.getAttribute("src");
            urls.add(src);
        }
        return urls;
    }
    
    /**
     * 获取状�?保存文件中的分片信息
     * @return pieces
     */
    public List<Piece> loadPieces() {
        List<Piece> pieces = new ArrayList<Piece>();
        try {
            doc = XmlOper.getDocument(configPath);
            Element file = doc.getDocumentElement();
            NodeList nPieces = file.getElementsByTagName("pieces");
            Element ePieces = (Element) nPieces.item(0);
            NodeList np = ePieces.getElementsByTagName("piece");
            int len = np.getLength();
            for (int i = 0; i < len; i++) {
                Element ep = (Element) np.item(i);
                int start = Integer.valueOf(ep.getAttribute("start"));
                int pos = Integer.valueOf(ep.getAttribute("pos"));
                int end = Integer.valueOf(ep.getAttribute("end"));
                Piece piece = new Piece(start, pos, end);
                pieces.add(piece);
            }
        } catch (Exception e) {
            Elog.log("载入状�?文件时遇到问�?" + getClass().getName());
        }
        return pieces;
    }
    
    /**
     * 将所有的分片信息保存至磁盘文件中,用于断点续传
     * @param pieces
     */
    public synchronized void savePieces(Vector<Piece> pieces) {
        Element file = doc.getDocumentElement();
        NodeList nodes = file.getElementsByTagName("pieces");
        Node node = nodes.item(0);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element ePieces = (Element) node;
            NodeList nPieces = ePieces.getElementsByTagName("piece");
            if (nPieces.getLength() <= 0) { // 保存�?��piece信息
                for (Piece piece : pieces) {
                    Element ePiece = doc.createElement("piece");
                    ePiece.setAttribute("start", String.valueOf(piece.getStart()));
                    ePiece.setAttribute("pos", String.valueOf(piece.getPos()));
                    ePiece.setAttribute("end", String.valueOf(piece.getEnd()));
                    ePieces.appendChild(ePiece);
                }
            } else {    // 更新
                List<Element> newPieces = new ArrayList<Element>();
                int len = nPieces.getLength();
                                
                for (Piece piece : pieces) {
                    boolean existPiece = false;
                    for (int i = 0; i < len; i++) {
                        Element ePiece = (Element) nPieces.item(i);
                        if (ePiece.getAttribute("start").equals(String.valueOf(piece.getStart()))) {
                            ePiece.setAttribute("pos", (String.valueOf(piece.getPos())));
                            ePiece.setAttribute("end", (String.valueOf(piece.getEnd())));
                            existPiece = true;
                            break;
                        }
                    }
                    // 如果不存在该分片的结点信息，则保存之
                    if (!existPiece) {
                        Element newPiece = doc.createElement("piece");
                        newPiece.setAttribute("start", (String.valueOf(piece.getStart())));
                        newPiece.setAttribute("pos", (String.valueOf(piece.getPos())));
                        newPiece.setAttribute("end", (String.valueOf(piece.getEnd())));
                        newPieces.add(newPiece);
                    }
                }
                for (Element e : newPieces) {
                    ePieces.appendChild(e);
                }
            }
            try {
                XmlOper.saveDocument(doc, configPath);
            } catch (Exception e) {
                Elog.log("状�?文件在保存分片信息时遇到问题!" + getClass().getName());
            }
        }
    }
    
    /** 当下载任务完成之�?完整下载�?,可以调用这个方法将状态文�?config)删除�?*/
    public boolean delete() {
        File f = new File(configPath);
        return f.delete();
    }
}
